const path = require('path');
const koaBody = require('koa-body');
const koaStatic = require('koa-static');
const todoRouter = require('./routers/todo');
const testRouter = require('./routers/test');
const userRouter = require('./routers/user');
const moneyGoalRouter = require('./routers/moneyGoal');
const mgRecordRouter = require('./routers/mgRecord');
const accountRouter = require('./routers/account');
const todayContentRouter = require('./routers/todayContent');
const todayPlanRouter = require('./routers/todayPlan');
const noteRouter = require('./routers/Note');
const R = require('./result/r')
const Koa = require('koa');
const JWTUtil = require('./util/JWTUtil')
const app = new Koa();

let log4Util = require('./logs/log4Util');

// logger

// 为应用使用中间件
// 静态文件中间件
app.use(koaStatic(path.join(__dirname, '../public')));
// 请求体 parse 中间件，用于 parse json 格式请求体
app.use(koaBody());
/** 若后面的路由抛错，则封装为错误响应返回
 * 错误响应格式为
 * {
 *   error: message
 * }
 */
app.use(async (ctx, next) => {
    const start = new Date();
    let ms = new Date() - start;
    await next();
    ctx.logger = log4Util
    try {
        // 开始进入到下一个中间件
        if (ctx.status === 404) {
            ctx.throw(404);
        }
        ms = new Date() - start;
        // 记录响应日志
        ctx.logger.logResponse(ctx, ms);
    } catch (error) {
        ms = new Date() - start;
        // 记录异常日志
        ctx.logger.logError(ctx, error, ms);
    }
});
//不需要检查的url集合
const noAuthArr = [
    "/api/user/loginUser",
    "/api/user/sendPhoneCode",
    "/api/user/loginByPhoneCode",
    "/api/user/registerUser",
];

function checkUrl(url) {
    for (const auth of noAuthArr) {
        if (url.indexOf(auth) !== -1) {
            return true;
        }
    }
}

//请求拦截用户认证
app.use(async (ctx, next) => {
    let url = ctx.request.url;
    // 不需要检查的url
    // console.log(url)
    if (checkUrl(url)) {
        await next();
    } else {
        let token = ctx.request.headers["authorization"];
        // console.log(token)
        // 解码
        try {
            let payload = await JWTUtil.verifyToken(token);
            console.log(payload)
            let {iat, exp} = payload;
            if (exp - iat >= 0) {
                // 未过期
                await next();
            } else {
                //过期
                ctx.body = R.authError("身份认证过期，请重新登录！")
            }
        } catch (e) {
            ctx.body = R.authError("认证异常，请重新登录！")
        }
    }
})


app.use(async function errorHandler(ctx, next) {
    try {
        await next();
    } catch (err) {
        // 抛出的错误可以附带 status 字段，代表 http 状态码
        // 若没有提供，则默认状态码为 500，代表服务器内部错误
        // console.log(err)
        ctx.status = err.status || 500;
        ctx.body = R.error(err.message);
    }
});

// 为应用使用路由定义
// 使用待办事项业务路由
app.use(todoRouter);
app.use(testRouter);
app.use(userRouter);
app.use(moneyGoalRouter);
app.use(mgRecordRouter);
app.use(accountRouter);
app.use(todayContentRouter);
app.use(todayPlanRouter);
app.use(noteRouter);


module.exports = app;
